package com.example.Windturbine.Service.Impl;

import com.example.Windturbine.Dao.MaterialDOMapper;
import com.example.Windturbine.Dao.MaterialInfoDOMapper;
import com.example.Windturbine.DataObject.MaterialDO;
import com.example.Windturbine.DataObject.MaterialInfoDO;
import com.example.Windturbine.Error.BusinessException;
import com.example.Windturbine.Error.EmBusinessError;
import com.example.Windturbine.Service.MaterialService;
import com.example.Windturbine.Service.Model.MaterialModel;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author 丁永新
 * @Date 2021/12/15
 */
@Service
public class MaterialServiceImpl implements MaterialService {
    @Resource
    private MaterialDOMapper materialMapper;

    @Resource
    private MaterialInfoDOMapper materialInfoMapper;

    //获取全部材料信息
    @Override
    public List<MaterialDO> getAll(Integer level) throws BusinessException {
        try {
            List<MaterialDO> res = materialMapper.getAll(level);
            if(res==null){
                throw new BusinessException(EmBusinessError.UNKNOWN_ERROR,"查询失败");
            }
            return res;
        } catch (Exception e) {
            throw new BusinessException(EmBusinessError.UNKNOWN_ERROR, "获取物质数据失败！");
        }
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, rollbackFor = Exception.class)
    public void submitSingle(MaterialModel materialModel) throws BusinessException {
        MaterialDO materialDO = materialDOConvertFromMaterialModel(materialModel);
        MaterialInfoDO materialInfoDO = materialInfoDOConvertFromMaterialModel(materialModel);
        try {
            int i = materialMapper.insertSelective(materialDO);
            materialInfoDO.setMaterialId(materialDO.getId());
            int insert = materialInfoMapper.insert(materialInfoDO);
            if(i==0||insert==0){
                throw new BusinessException(EmBusinessError.UNKNOWN_ERROR,"插入失败");
            }
        } catch (DuplicateKeyException ex) {
            throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR, "材料数据重复添加！");
        }
    }

    //获取一个材料的详细信息
    @Override
    public MaterialModel getDetailById(Integer id) throws BusinessException {
        MaterialInfoDO materialInfoDO = new MaterialInfoDO();
        MaterialModel materialModel = new MaterialModel();
        try {
            materialInfoDO = materialInfoMapper.selectByMaterialID(id);
            if(materialInfoDO==null){
                throw new BusinessException(EmBusinessError.UNKNOWN_ERROR,"查询失败");
            }
            materialModel = convertFromMaterialAndMaterInfo(new MaterialDO(), materialInfoDO);
        } catch (Exception e) {
            throw new BusinessException(EmBusinessError.UNKNOWN_ERROR, "材料信息不存在！");
        }

        return materialModel;
    }

    //根据名字获取第一个原材料的所有信息
    @Override
    public MaterialModel getDetailByName(String name, Integer level) throws BusinessException {
        List<MaterialDO> all = getAll(level);//获取用户的所有材料信息
        try {
            //获取名字相同的材料
            List<MaterialDO> materialDOS = new ArrayList<>();
            for (MaterialDO m : all) {
                if (m.getName().equals(name)) materialDOS.add(m);
            }
            //取第一个匹配到的材料
            MaterialDO first = materialDOS.get(0);
            MaterialModel res = getDetailById(first.getId());
            if (res == null){
                throw new BusinessException(EmBusinessError.UNKNOWN_ERROR, "材料" + name + "信息缺失!请及时补充材料背景数据");
            }
            return res;
        } catch (Exception e) {
            throw new BusinessException(EmBusinessError.UNKNOWN_ERROR, "材料" + name + "信息缺失!");
        }

    }


    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, rollbackFor = Exception.class)
    public void deleteById(Integer id) throws BusinessException {
        try {
            Integer n = materialMapper.deleteByPrimaryKey(id);
            if (n != 0){
                materialInfoMapper.deleteByMaterialId(id);
            }else{
                throw new BusinessException(EmBusinessError.UNKNOWN_ERROR, "材料信息删除出错 系统数据不可删除！");
            }
        } catch (DuplicateKeyException ex) {
            throw new BusinessException(EmBusinessError.UNKNOWN_ERROR, "材料信息删除出错！");
        }
    }


    private MaterialDO materialDOConvertFromMaterialModel(MaterialModel materialModel) {
        MaterialDO materialDO = new MaterialDO(null, materialModel.getName(), materialModel.getType(), materialModel.getUnit(), materialModel.getRegion(), materialModel.getOrigin(), materialModel.getComments(), materialModel.getLevel());
        return materialDO;
    }


    private MaterialInfoDO materialInfoDOConvertFromMaterialModel(MaterialModel materialModel) {
        MaterialInfoDO materialDO = new MaterialInfoDO(null, materialModel.get煤()
                , materialModel.get石油(), materialModel.get天然气(), materialModel.getCo()
                , materialModel.getCo2(), materialModel.getSo2(), materialModel.getNox()
                , materialModel.getCh4(), materialModel.getH2s(), materialModel.getHcl(),
                materialModel.getCod(), materialModel.getNh3(), materialModel.getCfc11()
                , materialModel.getCfc12(), materialModel.getCfc113(), materialModel.getId());
        return materialDO;
    }

    private MaterialModel convertFromMaterialAndMaterInfo(MaterialDO materialDO, MaterialInfoDO materialInfoDO) {
        MaterialModel materialModel = new MaterialModel(materialDO.getId(), materialDO.getName(), materialDO.getType(),
                materialDO.getUnit(), materialDO.getRegion(), materialDO.getOrigin(), materialDO.getComments(), materialDO.getLevel(),
                materialInfoDO.getId(), materialInfoDO.get煤(), materialInfoDO.get石油(), materialInfoDO.get天然气(), materialInfoDO.getCo(),
                materialInfoDO.getCo2(), materialInfoDO.getSo2(), materialInfoDO.getNox(), materialInfoDO.getCh4(), materialInfoDO.getH2s(),
                materialInfoDO.getHcl(), materialInfoDO.getCod(), materialInfoDO.getNh3(), materialInfoDO.getCfc11(),
                materialInfoDO.getCfc12(), materialInfoDO.getCfc113());
        return materialModel;
    }

}
